//: Playground - noun: a place where people can play

import UIKit

// 定义错误协议
enum ScoreInputError: Error {

    case lowZero(name:String, score:Float)
    case highHudred(name: String, score: Float)
}

// 定义含有异常机制的函数

func inputStudentName(name:String, score: Float) throws -> Bool {

    if score < 0 {
        throw ScoreInputError.lowZero(name: name, score: score)
    } else if score > 100 {
    
        throw ScoreInputError.highHudred(name: name, score: score)
    }
    
    return true
}

// 调用函数

do {

    let result = try inputStudentName(name: "zhangdan", score: -300)

} catch ScoreInputError.lowZero(let name, let score) {

    print("异常：\(name)的成绩为\(score)----小于0")
} catch ScoreInputError.highHudred(let name, let score) {
    
    print("异常：\(name)的成绩为\(score)----大于100")
}

// 定义异常
enum OSUserLoginError :Error{
    case AllNoComplete
    case UserNameEmpty
    case PasswordEmpty(userName:String)
}
// 定义含有异常机制的函数
func verifyUserName(userName:String,password:String)throws -> Bool{
    if userName == "" && password == "" {
        throw OSUserLoginError.AllNoComplete
    }else if (userName == "" && password != ""){
        throw OSUserLoginError.UserNameEmpty
    }else if (userName != "" && password == ""){
        throw OSUserLoginError.PasswordEmpty(userName: userName)
    }
    return true
}
// 使用含有异常的函数
do
{
    try  verifyUserName(userName: "", password: "33")
}catch OSUserLoginError.PasswordEmpty(let userName){
    print("用户:" + userName + "输入的密码为空")
} catch OSUserLoginError.UserNameEmpty{
    print("用户名为空")
} catch{
    print(error)
}

// where 在错误类型的使用
enum ErrorType:Error {
    case success
    case error(code:Int)
}


func inputScore(score:Int) throws->Bool{
    
    if score < 0{
        throw ErrorType.error(code: 0)
    }else if score > 100 {
        throw ErrorType.error(code: 1)
    }
    return true
}

do {
    let score =  try inputScore(score: 200)
}catch ErrorType.error(let x) where x == 0{ // 可以做判断错误类型
    
    print(x)
}catch ErrorType.error(let x) where x == 1{// 可以做判断错误类型
    
    print(x)
}catch{
    print(error)
}

/**
 1.类中使用defer,在对象方法中,使用defer,在defer块中,调用属性之前,必须初始化所有存储属性,重要事说三遍,所有的存储属性,所有的,存储属性
 2.defer 在定义的当前作用域最后一步执行
*/

// 定义错误协议
enum StudentError:Error{
    case NameEmpty
    case ScoreLowZero
}
// 定义学生类
class Student{
    var name:String = "123"
    var score:Float = 0
    var userIcon:UnsafeMutableRawPointer = malloc(40*40*4) // 定义用户图像数据流
    init(name:String)throws{
        if name == ""{
            defer{
                free(self.userIcon)
                print("第2步发生异常清理内存")
            }
            print("第1步 抛出异常")
            throw StudentError.NameEmpty
        }
        self.name = name
    }
}
// 调用函数
do{
    let student = try Student(name: "")
}catch {
    print(error)
}

// try 、try!、try? 的用法

// A.try  我们发现print("运行结果(student)") 这句代码没有执行,说明发生了异常,后面的代码不会执行,但没有报错提示

//let student = try Student(name: "")
//print("运行结果\(student)")

// try! 一旦发生异常,系统会报错,后面的代码不再继续执行
//
//let student = try! Student(name: "")
//print("运行结果\(student)")

// C.try? 如果发生异常则返回nil,如果没有发生异常,则返回可选值,我们在使用时,需要解包可选值!

let student = try? Student(name: "234")
print("运行结果\(student)")

public enum OSNetError:Error{
    /// 错误类型枚举值
    case requestError(RequestError)
    case responseError(ResponseError)
    
    
    /// 请求错误异常
    public  enum RequestError{
        case invalidUrl(url:URL)
        case parameterException
    }
    
    /// 响应错误异常
    public  enum ResponseError:Int{
        case dataFileNil
        case missingContentType
        case unacceptableStatusCode
        case dataFileReadFailed
    }
    
}

func requestUrl(url:URL)throws{
    if !url.absoluteString.contains("http"){
        throw OSNetError.requestError(.invalidUrl(url:url))
    }
}

// 如果你要使用的值有可能为nil,你最好的写法应该像下面这样 guard
//guard let filter = CIFilter(name: "CIGaussianBlur",
//                            withInputParameters: [String : Any]?) else { fatalError() }

